/*
 * tcp_server.cpp
 *
 *  Created on: 2016-2-28
 *      Author: ZhangXiyin
 */

#include "tcp_server.h"
#include <boost/asio/placeholders.hpp>
#include "thread/single/service.h"
#include "../../base/connection_handler_base.hpp"
#include "tcp_connection.h"
#include "tcp_socket.h"

namespace eyas {
namespace io {

tcp_server::tcp_server()
:io_service_(service::instance()->io_service())
, disable_(false){}

tcp_server::~tcp_server() {
	this->close();
}

void tcp_server::handle_accept(connection_ptr& new_connection, const boost::system::error_code& error){
	if(error){
		{
			boost::recursive_mutex::scoped_lock lck(this->mutex_);
			if(disable_)
				return;
			if (error.value() != boost::system::errc::operation_canceled) {
				std::cerr << boost::system::system_error(error).what() << std::endl;
			}
			acceptor_ptr_->close();
		}
		if(nullptr != this->conn_callback_ptr_){
			this->conn_callback_ptr_->call(new_connection, error);
		}
		return;
	}
	if(nullptr != this->conn_callback_ptr_){
		this->conn_callback_ptr_->call(new_connection, error);
	}
	boost::recursive_mutex::scoped_lock lck(this->mutex_);
	if(disable_)
		return;
	this->ready_accept();
}
void tcp_server::ready_accept(){
	tcp_socket_ptr skt_ptr = eyas::gc::create_new<tcp_socket>(this->io_service_);
	connection_ptr connPtr = eyas::gc::create_new<tcp_connection>(skt_ptr);
	acceptor_ptr_->async_accept(skt_ptr->get_socket(),
			boost::bind(&tcp_server::handle_accept,
					this->shared_from_this(),
					connPtr,
					boost::asio::placeholders::error));
}

void tcp_server::close(){
	boost::recursive_mutex::scoped_lock lck(this->mutex_);
	if(!this->disable_){
		this->disable_ = true;
		if(nullptr != this->acceptor_ptr_){
			this->acceptor_ptr_->close();
		}
	}
}
} /* namespace io */
} /* namespace eyas */
